﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.UI;
using Windows.UI.Core;
using Windows.UI.Xaml.Media;

namespace WinRTSock.Test
{
    public class TestItemViewModel : INotifyPropertyChanged
    {
        private CoreDispatcher dispatcher;
        private bool? result;
        private SolidColorBrush resultIndicator;
        private string notes;
        private string testName;
        private Func<IAsyncOperation<Boolean>> testFunction;
        private Action setupAction;
        private Action teardownAction;

        public bool? Result
        {
            get { return this.result; }
            set
            {
                if (this.result == value)
                    return;
                this.result = value;
                this.OnPropertyChanged("Result");
            }
        }
        public SolidColorBrush ResultIndicator
        {
            get { return this.resultIndicator; }
            set
            {
                if (this.resultIndicator == value)
                    return;
                this.resultIndicator = value;
                this.OnPropertyChanged("ResultIndicator");
            }
        }
        public string Notes
        {
            get { return this.notes; }
            set
            {
                if (this.notes == value)
                    return;
                this.notes = value;
                this.OnPropertyChanged("Notes");
            }
        }
        public string TestName
        {
            get { return this.testName; }
            set
            {
                if (this.testName == value)
                    return;
                this.testName = value;
                this.OnPropertyChanged("TestName");
            }
        }
        public DelegateCommand Command { get; private set; }

        public TestItemViewModel()
        {
            this.Command = new DelegateCommand(this.onCommand);
        }
        public static TestItemViewModel Create(string testName, Color resultIndicator, string notes, CoreDispatcher dispatcher, Action setupAction, Func<IAsyncOperation<Boolean>> testToRun, Action teardownAction)
        {
            var result = new TestItemViewModel();
            result.dispatcher = dispatcher;
            result.TestName = testName;
            result.Notes = notes;
            result.ResultIndicator = new SolidColorBrush(resultIndicator);
            result.testFunction = testToRun;
            result.setupAction = setupAction;
            result.teardownAction = teardownAction;
            return result;
        }

        public async Task RunTest()
        {
            this.Notes = "Running...";
            this.ResultIndicator = new SolidColorBrush(Colors.Yellow);
            var result = await this.testFunction();
            if (result)
            {
                this.Result = true;
                this.ResultIndicator = new SolidColorBrush(Colors.Green);
                this.Notes = "Complete. Result: PASS.";
            }
            else
            {
                this.Result = false;
                this.ResultIndicator = new SolidColorBrush(Colors.Red);
                this.Notes = "Complete. Result: FAIL.";
            }
            this.teardownAction();
        }

        public void Reset()
        {
            this.Result = null;
            this.ResultIndicator = new SolidColorBrush(Colors.Gray);
            this.Notes = "Not run";
            this.setupAction();
        }

        private async void onCommand()
        {
            this.Reset();
            await this.RunTest();
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

    }
}
